package com.sh.data.engine.web.webapi.controller.integration;

import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.integration.DataSourceDTO;
import com.sh.data.engine.application.model.dto.integration.DataSourceDetailDTO;
import com.sh.data.engine.application.model.dto.integration.HiveSiteXmlUploadDTO;
import com.sh.data.engine.application.model.request.integration.*;
import com.sh.data.engine.application.service.integration.DataSourceApplicationService;
import com.sh.data.engine.common.annotation.crypto.EncryptMethod;
import com.sh.data.engine.common.constants.HttpStatus;
import com.sh.data.engine.common.constants.code.BizCodes;
import com.sh.data.engine.common.enumDefinition.ProjectStatisticTypeEnum;
import com.sh.data.engine.common.exception.BusinessException;
import com.sh.data.engine.domain.annotation.LogExecution;
import com.sh.data.engine.domain.annotation.ProjectStatisticExecution;
import com.sh.data.engine.domain.annotation.userlog.Business;
import com.sh.data.engine.domain.annotation.userlog.EngineOperation;
import com.sh.data.engine.web.webapi.controller.base.response.RestResponseEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 数据源管理
 *
 * @author: mengzheng.mhc
 * @date: 2024/5/27 13:40
 */
@Validated
@RestController
@RequestMapping("/normalization/datasource")
@Tag(name = "数据源管理", description = "数据源管理API")
public class DataSourceController {

    @Autowired
    private DataSourceApplicationService dataSourceApplicationService;

    @GetMapping("/getDSPageList")
    @Operation(summary = "获取数据源列表")
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<PagerResponse<DataSourceDTO>> getDSPageList(
        @Parameter(description = "数据源类型") @RequestParam(required = false) String dsType,
        @Parameter(description = "数据源名称") @RequestParam(required = false) String dsName,
        @Parameter(description = "连接状态 0-失败 1-成功") @RequestParam(required = false) Integer status,
        @Parameter(description = "当前页", schema = @Schema(defaultValue = "1")) @RequestParam(required = false, defaultValue = "1") Integer pageNum,
        @Parameter(description = "每页大小", schema = @Schema(defaultValue = "10")) @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        var result = dataSourceApplicationService.getDataSourcePageList(dsType, dsName, status, pageNum, pageSize);
        return RestResponseEntity.success(result);
    }

    @Operation(summary = "保存/更改RDBMS数据源")
    @PostMapping("/saveRdbms")
    @EncryptMethod
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
    public RestResponseEntity<Boolean> saveDataSourceRdbms(
        @Valid @RequestBody DataSourceRdbmsSaveRequest dataSourceSaveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceSaveRequest);
        return RestResponseEntity.success(result);
    }

    @Operation(summary = "保存/更改hive数据源")
    @PostMapping("/saveHive")
    @EncryptMethod
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceHive(
        @RequestBody @Valid DataSourceHiveSaveRequest dataSourceHiveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceHiveRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改kafka")
    @PostMapping("/saveKafka")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
    public RestResponseEntity<Boolean> saveDataSourceKafka(
        @RequestBody @Valid DataSourceSaveRequest dataSourceSaveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceSaveRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改Mqtt")
    @PostMapping("/saveMqtt")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceMqtt(
        @RequestBody @Valid DataSourceSaveRequest dataSourceSaveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceSaveRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改MongoDB")
    @PostMapping("/saveMongo")
    @EncryptMethod
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
    public RestResponseEntity<Boolean> saveDataSourceMongo(
        @RequestBody @Valid DataSourceMongoSaveRequest dataSourceMongoRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceMongoRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改HBase数据源")
    @PostMapping("/saveHBase")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceHBase(
        @RequestBody @Valid DataSourceSaveRequest dataSourceSaveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceSaveRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改HDFS数据源")
    @PostMapping("/saveHDFS")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceHDFS(
        @RequestBody @Valid DataSourceHDFSSaveRequest dataSourceHDFSRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceHDFSRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改Dgraph")
    @PostMapping("/saveDgraph")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDgraph(
        @RequestBody @Valid DataSourceSaveRequest dataSourceSaveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceSaveRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改IOTDB数据源")
    @PostMapping("/saveIoTDB")
    @EncryptMethod
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceIotDB(
        @RequestBody @Valid DataSourceIotDBSaveRequest dataSourceIotDBRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceIotDBRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改InfluxDB数据源")
    @PostMapping("/saveInfluxDB")
    @EncryptMethod
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceInfluxDB(
        @RequestBody @Valid DataSourceInfluxDBSaveRequest influxDBRequest) {
        var result = dataSourceApplicationService.saveDataSource(influxDBRequest);
        return new RestResponseEntity<>(result);
    }

    @Operation(summary = "保存/更改opentsdb数据源")
    @PostMapping("/saveOpentsdb")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.ADD_UPDATE)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> saveDataSourceOpentsdb(
        @RequestBody @Valid DataSourceSaveRequest dataSourceSaveRequest) {
        var result = dataSourceApplicationService.saveDataSource(dataSourceSaveRequest);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/deleteDataSourceById")
    @Operation(summary = "删除数据源")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.REGISTER_DS)
    @LogExecution(operation = EngineOperation.DEL, business = Business.数据源)
//    @Log(business = Business.数据源, operation = Operation.DEL)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<Boolean> deleteDataSourceById(Long id) {
        var result = dataSourceApplicationService.dropDataSourceById(id);
        return new RestResponseEntity<>(result);
    }

    @GetMapping("/getDataSourceDetailById")
    @Operation(summary = "获取数据源详情")
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<DataSourceDetailDTO> getDataSourceDetailById(Long id) {
        var result = dataSourceApplicationService.getDataSourceDetailById(id);
        return new RestResponseEntity<>(result);
    }

    @GetMapping("/getLastUpdateTime")
    @Operation(summary = "获取数据源列表")
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<String> getLastUpdateTime() {
        String lastUpdate = dataSourceApplicationService.getLastUpdateTime();
        return new RestResponseEntity<>(lastUpdate);
    }

    @PostMapping("/getSchemas")
    @Operation(summary = "查询PG的schema")
    @EncryptMethod
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<List<String>> getSchemas(
        @RequestBody @Valid DataSourceSchemaQueryRequest schemaRequest) {
        var result = dataSourceApplicationService.getSchemas(schemaRequest);
        return new RestResponseEntity<>(result);
    }

    @GetMapping("/tableExist")
    @Operation(summary = "判断数据表是否存在")
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> tableExist(
        @Parameter(description = "数据源id") @RequestParam(required = true) Long dsId,
        @Parameter(description = "数据表名称") @RequestParam(required = true) String tableName) {
        var result = dataSourceApplicationService.tableExist(dsId, tableName);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/uploadHiveSiteFile")
    @Operation(summary = "上传hive-site.xml文件")
    @LogExecution(operation = EngineOperation.UPLOAD, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 1, isAdd = 1)
    public RestResponseEntity<HiveSiteXmlUploadDTO> uploadHiveSiteFile(@RequestPart("file") MultipartFile file) {
        if (file.isEmpty() || file.getSize() == 0) {
            throw new BusinessException(BizCodes.REQUEST_PARAMETER_ERROR, HttpStatus.BAD_REQUEST);
        }

        var result = dataSourceApplicationService.uploadHiveSiteXml(file);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testRdbmsConnection")
    @Operation(summary = "测试数rdbms据源")
    @EncryptMethod
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testRdbmsConnection(
        @RequestBody @Valid DataSourceConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testHiveConnection")
    @Operation(summary = "测试Hive数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testHiveConnection(
        @RequestBody @Valid DataSourceHiveConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testMongoConnection")
    @Operation(summary = "测试Mongo数据源")
    @EncryptMethod
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testMongoConnection(
        @RequestBody @Valid DataSourceMongoConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testMqttConnection")
    @Operation(summary = "测试MQTT数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testMqttConnection(
        @RequestBody @Valid DataSourceConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testDrapghConnection")
    @Operation(summary = "测试drapgh数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testDrapghConnection(
        @RequestBody @Valid DataSourceConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testHBaseConnection")
    @Operation(summary = "测试HBase数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testHBaseConnection(
        @RequestBody @Valid DataSourceConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testKafkaConnection")
    @Operation(summary = "测试Kafka数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testKafkaConnection(
        @RequestBody @Valid DataSourceConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testHDFSConnection")
    @Operation(summary = "测试数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testHDFSConnection(
        @RequestBody @Valid DataSourceHDFSConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testOpentsdbConnection")
    @Operation(summary = "测试数据源")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testOpentsdbConnection(
        @RequestBody @Valid DataSourceConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testIoTDBConnection")
    @Operation(summary = "测试IOTDB数据源")
    @EncryptMethod
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testIoTDBConnection(
        @RequestBody @Valid DataSourceIoTDBConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }

    @PostMapping("/testInfluxDBConnection")
    @Operation(summary = "测试InfluxDB数据源")
    @EncryptMethod
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.数据源)
//    @AuthorityAnnotation(menuId = MenuEnumNew.SJGL, readWriteStatus = 0, isAdd = 1)
    public RestResponseEntity<Boolean> testInfluxDBConnection(
        @RequestBody @Valid DataSourceInfluxDBConnectionRequest request) {
        var result = dataSourceApplicationService.testDataSourceConnection(request);
        return new RestResponseEntity<>(result);
    }
}
